package com.siwei.mes.entity.experiment;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.siwei.mes.common.validator.UpdateGroup;
import com.siwei.mes.entity.experiment.coarseAggregate.CoarseAggregateSfx;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.apache.commons.lang.StringUtils;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;


/**
 * 试验台账json详情(ExperimentDetail)实体类
 *
 * @author linzi
 * @since 2023-12-27 23:30:45
 */
@Data
@Accessors(chain = true)
@Table(name = "pk_experiment_detail")
@ApiModel(value = "ExperimentDetail", description = "试验台账json详情")
public class ExperimentDetail implements Serializable {
    private static final long serialVersionUID = -75833960579418596L;
    /**
     * 主键id
     */
    @Id
    @ApiModelProperty(value = "试验台账json详情主键ID", name = "id")
    @NotNull(groups = {UpdateGroup.class}, message = "主键id为空")
    private Long id;
    /**
     * 试验台账id
     */
    @Column(name = "experiment_id")
    @ApiModelProperty(value = "试验台账id", name = "experimentId")
    @NotNull(groups = {UpdateGroup.class}, message = "试验台账id为空")
    private Long experimentId;
    /**
     * 检查类型 1-快检 2-批检
     */
    @Column(name = "check_type")
    @ApiModelProperty(value = "检查类型 1-快检 2-批检", name = "checkType")
    @NotNull(groups = {UpdateGroup.class}, message = "检查类型为空")
    private Integer checkType;
    /**
     * 试验项目code
     */
    @Column(name = "test_project_code")
    @ApiModelProperty(value = "试验项目code", name = "testProjectCode")
    @NotBlank(groups = {UpdateGroup.class}, message = "试验项目code为空")
    private String testProjectCode;
    /**
     * 试验项目名称
     */
    @Column(name = "test_project_name")
    @ApiModelProperty(value = "试验项目名称", name = "testProjectName")
    @NotBlank(groups = {UpdateGroup.class}, message = "试验项目名称为空")
    private String testProjectName;
    /**
     * 对应json
     */
    @Column(name = "obj_json")
    @ApiModelProperty(value = "对应json", name = "objJson")
    @NotNull(groups = {UpdateGroup.class}, message = "对应json为空")
    private JSONObject objJson;
    /**
     * 对应图片  多个用逗号隔开
     */
    @Column(name = "obj_img")
    @ApiModelProperty(value = "对应图片  多个用逗号隔开", name = "objImg")
    private String objImg;
    /**
     * 配合比编码（自动生成）
     */
    @Column(name = "proportion_no")
    @ApiModelProperty(value = "配合比编码（自动生成）", name = "proportionNo")
    private String proportionNo;
    /**
     * 创建人
     */
    @Column(name = "creater")
    @ApiModelProperty(value = "创建人", name = "creater")
    private Long creater;
    /**
     * 创建时间
     */
    @Column(name = "create_time")
    @ApiModelProperty(value = "创建时间", name = "createTime")
    private Date createTime;
    /**
     * 修改人
     */
    @Column(name = "updater")
    @ApiModelProperty(value = "修改人", name = "updater")
    private Long updater;
    /**
     * 更新时间
     */
    @Column(name = "update_time")
    @ApiModelProperty(value = "更新时间", name = "updateTime")
    private Date updateTime;
    /**
     * 是否删除  1-删除
     */
    @Column(name = "is_del")
    @ApiModelProperty(value = "是否删除  1-删除", name = "isDel")
    private Integer isDel;
    /**
     * 试验依据
     */
    @Column(name = "experiment_gist")
    @ApiModelProperty(value = "试验依据", name = "experimentGist")
    private String experimentGist;
    /**
     * 判断依据
     */
    @Column(name = "judge_gist")
    @ApiModelProperty(value = "判断依据", name = "judgeGist")
    private String judgeGist;
    /**
     * 主要仪器设备
     */
    @Column(name = "equipment")
    @ApiModelProperty(value = "主要仪器设备编号", name = "equipment")
    private String equipment;
    /**
     * 温度
     */
    @Column(name = "temperature")
    @ApiModelProperty(value = "温度", name = "temperature")
    private String temperature;
    /**
     * 湿度
     */
    @Column(name = "humidness")
    @ApiModelProperty(value = "湿度", name = "humidness")
    private String humidness;
    /**
     * 试验状态
     */
    @Column(name = "status")
    @ApiModelProperty(value = "试验状态", name = "status")
    private String status;


    @Transient
    @ApiModelProperty(value = "排序")
    private Integer sortNo;

    @Transient
    @ApiModelProperty(value = "多个试验台账id")
    private List<Long> experimentIdList;

    public ExperimentDetail init(boolean isCreate) {
        this.setUpdater(StpUtil.isLogin() ? StpUtil.getLoginIdAsLong() : null)
                .setUpdateTime(new Date());
        if (isCreate) {
            this.setCreater(StpUtil.isLogin() ? StpUtil.getLoginIdAsLong() : null)
                    .setCreateTime(new Date()).setIsDel(0);
        }
        return this;
    }

    public ExperimentDetail erpInit(boolean isCreate) {
        this.setUpdateTime(new Date());
        if (isCreate) {
            this.setCreateTime(new Date()).setIsDel(0);
        }
        return this;
    }

    public ExperimentDetail tcInit(boolean isCreate) {
        this.setUpdateTime(new Date());
        if (isCreate) {
            this.setCreateTime(new Date()).setIsDel(0);
        }
        return this;
    }

    public void setSfxJson(Experiment experiment, ExperimentDetail detail) {
        CoarseAggregateSfx coarseSfx = detail.getObjJson().toJavaObject(CoarseAggregateSfx.class);
        List<CoarseAggregateSfx.SfxInfo> sfxInfoList = coarseSfx.getSfxInfo();
        String materialsSpecs = experiment.getMaterialsSpecs();
        List skgjzj = new ArrayList<>();
        if (materialsSpecs.contains("5～10")) {
            skgjzj.add("筛底");
            skgjzj.add("2.50mm");
            skgjzj.add("5.00mm");
            skgjzj.add("10.0mm");
            skgjzj.add("16.0mm");
        } else if (materialsSpecs.contains("5～16")) {
            skgjzj.add("筛底");
            skgjzj.add("2.50mm");
            skgjzj.add("5.00mm");
            skgjzj.add("10.0mm");
            skgjzj.add("16.0mm");
            skgjzj.add("20.0mm");
        } else if (materialsSpecs.contains("5～20")) {
            skgjzj.add("筛底");
            skgjzj.add("2.50mm");
            skgjzj.add("5.00mm");
            skgjzj.add("10.0mm");
            skgjzj.add("20.0mm");
            skgjzj.add("25.0mm");
        } else if (materialsSpecs.contains("5～25")) {
            skgjzj.add("筛底");
            skgjzj.add("2.50mm");
            skgjzj.add("5.00mm");
            skgjzj.add("16.0mm");
            skgjzj.add("25.0mm");
            skgjzj.add("31.5mm");
        } else if (materialsSpecs.contains("5～31.5")) {
            skgjzj.add("筛底");
            skgjzj.add("2.50mm");
            skgjzj.add("5.00mm");
            skgjzj.add("10.0mm");
            skgjzj.add("20.0mm");
            skgjzj.add("31.5mm");
            skgjzj.add("40.0mm");
        } else if (materialsSpecs.contains("5～40")) {
            skgjzj.add("筛底");
            skgjzj.add("5.00mm");
            skgjzj.add("10.0mm");
            skgjzj.add("20.0mm");
            skgjzj.add("40.0mm");
            skgjzj.add("50.0mm");
        }
        List<CoarseAggregateSfx.SfxInfo> sfxInfoListNew = sfxInfoList.stream()
                .filter(sfxInfo -> skgjzj.contains(sfxInfo.getSkgjzj()))
                .collect(Collectors.toList());
        coarseSfx.setSfxInfo(sfxInfoListNew);
        detail.setObjJson((JSONObject) JSONObject.toJSON(coarseSfx));
    }



    public static String extractDates(JSONArray jsonArray) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
        AtomicReference<Date> minDate = new AtomicReference<>(new Date(Long.MAX_VALUE));
        AtomicReference<Date> maxDate = new AtomicReference<>(new Date(Long.MIN_VALUE));
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject json = jsonArray.getJSONObject(i);
            traverseJson(json, formatter,minDate,maxDate);
        }

        String result = "";
        String minDateStr = "";
        if (minDate.get() != null && !minDate.get().equals(new Date(Long.MAX_VALUE))) {
            result += formatter.format(minDate.get());
            minDateStr = formatter.format(minDate.get());
        }
        if (maxDate.get() != null && !maxDate.get().equals(new Date(Long.MIN_VALUE))) {
            String maxDateStr = formatter.format(maxDate.get());
            if(!maxDateStr.equals(minDateStr)){
                if (StringUtils.isNotBlank(result)) {
                    result += "~";
                }
                result += formatter.format(maxDate.get());
            }
        }
        return result;
    }

    public static Date extractEndDate(JSONArray jsonArray) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
        AtomicReference<Date> minDate = new AtomicReference<>(new Date(Long.MAX_VALUE));
        AtomicReference<Date> maxDate = new AtomicReference<>(new Date(Long.MIN_VALUE));
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject json = jsonArray.getJSONObject(i);
            traverseJson(json, formatter,minDate,maxDate);
        }


        if (maxDate.get() != null && !maxDate.get().equals(new Date(Long.MIN_VALUE))) {
            return maxDate.get();
        }
        return new Date();
    }

    private static void traverseJson(JSONObject json, SimpleDateFormat formatter,AtomicReference<Date> minDate,AtomicReference<Date> maxDate) {
        for (String key : json.keySet()) {
            if(key != null){
                Object value = json.get(key);
                if (value instanceof JSONObject) {
                    traverseJson((JSONObject) value, formatter,minDate,maxDate);
                } else if (value instanceof JSONArray) {
                    for (int i = 0; i < ((JSONArray) value).size(); i++) {
                        traverseJson(((JSONArray) value).getJSONObject(i), formatter,minDate,maxDate);
                    }
                } else if (("jcrq".equals(key) || "jcrq3d".equals(key) || "jcrq7d".equals(key) || "jcrq28d".equals(key)) && value instanceof String) {
                    Date date;
                    try {
                        if (StringUtils.isNotBlank((String) value)) {
                            date = formatter.parse((String) value);
                            minDate.set(minDate.get().before(date) ? minDate.get() : date);
                            maxDate.set(maxDate.get().after(date) ? maxDate.get() : date);
                        }
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}
